/*
PearReview - The peer review assistant.
Copyright (C) 2009  Dimitrij Pankratz, Anton Musichin
http://www.pearreview.com, info@pearreview.com

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

package com.pearreview.ui.table;

import java.util.List;

import javax.swing.table.AbstractTableModel;

import com.pearreview.application.Messages;
import com.pearreview.util.review.Finding;
import com.pearreview.util.review.IdArrayList;
import com.pearreview.util.review.IdList;
import com.pearreview.util.review.Severity;

public class FindingTableModel extends AbstractTableModel {
	private static final long serialVersionUID = 5019891558366400937L;
	private String[] columns = {"Id", 
			Messages.getString("PearReview.Scribe.findings.description"), 
			Messages.getString("PearReview.Scribe.findings.severity"),
			Messages.getString("PearReview.Scribe.findings.references"),
			Messages.getString("PearReview.Scribe.findings.aspects"),
			Messages.getString("PearReview.Scribe.findings.images")};
	
	private IdList<Finding> findings;
	
	/**
	 * Sets column names
	 * @param columns
	 */
	public void setColumns(String[] columns) {
		this.columns = columns;
		
		fireTableStructureChanged();
	}
	
	/**
	 * Returns column names
	 * @return
	 */
	public String[] getColumns() {
		return columns;
	}
	
	/**
	 * Sets findings
	 * @param findings findings to set
	 */
	public void setFindings(IdList<Finding> findings) {
		this.findings = findings;
		fireTableDataChanged();
	}
	
	/**
	 * Adds Finding to the model
	 * @param finding finding to add
	 * @return index of added finding
	 */
	public int addFinding(Finding finding) {
		if(findings == null)
			findings = new IdArrayList<Finding>();
		
		findings.add(finding);
		
		int index = findings.indexOf(finding);
		
		fireTableRowsInserted(index, index);
		
		return index;
	}
	
	/**
	 * Removes finding at index
	 * @param index index of finding to remove
	 * @return the removed finding
	 */
	public Finding removeFinding(int index) {
		Finding finding = findings.remove(index);
		
		fireTableRowsDeleted(index, index);
		
		return finding;
	}
	
	/**
	 * Removes finding
	 * @param finding finding to remove
	 * @return index of removed finding
	 */
	public int removeFinding(Finding finding) {
		int index = findings.indexOf(finding);
		
		removeFinding(index);
		
		return index;
	}
	
	/**
	 * Count of findings, where are added to the model
	 * @return findings count
	 */
	public int getFindingCount() {
		if(findings == null)
			return 0;
		return findings.size();
	}
	
	/**
	 * Returns finding at specified index
	 * @param index index of finding
	 * @return finding at specified index
	 */
	public Finding getFinding(int index) {
		return findings.get(index);
	}
	
	/**
	 * Returns findings, where are added to the model
	 * @return findings
	 */
	public IdList<Finding> getFindings() {
		return findings;
	}
	
	/**
	 * Validate added finding 
	 * @param finding finding to validate
	 */
	public void validateFinding(Finding finding) {
		validateFinding(indexOfFinding(finding));
	}
	
	/**
	 * Validate added finding 
	 * @param index index of finding to validate
	 */
	public void validateFinding(int index) {
		fireTableRowsUpdated(index, index);
	}
	
	/**
	 * Returns index of specified finding
	 * @param finding finding to search for
	 * @return index of finding
	 */
	public int indexOfFinding(Finding finding) {
		if(findings == null)
			return -1;
		return findings.indexOf(finding);
	}
	
	/**
	 * Removes all findings in the model
	 */
	public void clearFindings() {
		findings = null;
		fireTableDataChanged();
	}

	@Override
	public int getColumnCount() {
		if(columns == null)
			return 0;
		return columns.length;
	}

	@Override
	public int getRowCount() {
		return getFindingCount();
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		if(rowIndex < 0 || rowIndex >= getRowCount())
			return null;
		
		Finding finding  = findings.get(rowIndex);
		switch(columnIndex) {
		case 0:
			return finding;
		case 1:
			return finding.getDescription();
		case 2:
			return finding.getSeverity();
		case 3:
			return finding.getReferences();
		case 4:
			return finding.getAspects();
		case 5:
			return finding.getExternalReferences();
		default:
			return null;
		}
	}
	
	@Override
	public Class<?> getColumnClass(int columnIndex) {
		switch(columnIndex) {
		case 0:
			return Finding.class;
		case 1:
			return String.class;
		case 2:
			return Severity.class;
		case 3:
			return List.class;
		case 4:
			return List.class;
		case 5:
			return List.class;
		default: 
			return super.getColumnClass(columnIndex);
		}
	}
	
	@Override
	public String getColumnName(int column) {
		return columns[column];
	}
}
